package mn.more.wits.client;

import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.*;
import mn.more.wits.client.dto.ExamListDTO;
import mn.more.wits.client.dto.ExamSummaryDTO;
import mn.more.wits.client.dto.Payload;
import mn.more.wits.client.gui.WitsTable;
import mn.more.wits.client.util.ClientModelUtil;
import mn.more.wits.client.util.FormatUtil;
import net.mygwt.ui.client.Events;
import net.mygwt.ui.client.Registry;
import net.mygwt.ui.client.Style;
import net.mygwt.ui.client.event.BaseEvent;
import net.mygwt.ui.client.event.Listener;
import net.mygwt.ui.client.widget.ContentPanel;
import net.mygwt.ui.client.widget.Viewport;
import net.mygwt.ui.client.widget.layout.BorderLayoutData;
import net.mygwt.ui.client.widget.table.DateTimeCellRenderer;
import net.mygwt.ui.client.widget.table.NumberCellRenderer;
import net.mygwt.ui.client.widget.table.TableColumn;
import net.mygwt.ui.client.widget.table.TableItem;

/**
 * @author $Author: mikeliucc $
 * @version $Revision: 119 $
 */
public class ExamTakerStartPage extends ContentPanel {

	public static final String ID = "start-page";
	private ContentPanel availableTests;

	public ExamTakerStartPage() {
		super(Style.COLLAPSE);
		setId(ID);
		setStyleName("pn-startpage");
		setPadding(10);
		setScrollEnabled(true);
		setWidth("100%");
		setFrame(true);

		Registry.register(ID, this);

		init();
	}

	public void init() {
		removeAll();
		initProfile();
		initAvailableTests();
		initTestResults();
	}

	private void initProfile() {
		// todo: investigate if creating a new instance of UserProfile will have any adverse effect on memorry
		// (albeilt client-side)
		UserProfile profile = new UserProfile();
		add(profile);
	}

	private void initAvailableTests() {
		availableTests = new ContentPanel(Style.HEADER | Style.COLLAPSE);
		availableTests.setText("Available Tests");
		availableTests.setWidth("100%");
		availableTests.setFrame(false);
		availableTests.setStyleName("pn-avail-tests");
		add(availableTests);

		//DummyBootstrap.addBeginTestButton(availableTests);
		//DummyBootstrap.addAvailableExams(availableTests);
		ExamSessionManager.App.getInstance().getAvailableExams(new AsyncCallback() {

			public void onFailure(Throwable caught) {
				AppContext.showMessageBox("WITS", Style.ICON_ERROR, Style.OK, caught.getMessage());
			}

			public void onSuccess(Object result) {
				availableTests.removeAll();
				if (result == null) {
					// todo: i18n
					Label label = new Label("No exams available.");
					availableTests.add(label);
				} else {
					Payload payload = (Payload) result;
					ExamListDTO availableExams = new ExamListDTO();
					ClientModelUtil.toModel(payload, availableExams);
					WitsTable availableExamTable = toTable(availableExams);
					availableExamTable.recalculate();
					availableTests.add(availableExamTable);
					availableTests.setSize(availableExamTable.getWidth(), availableExamTable.getHeight());
				}
				availableTests.setPadding(2);
				availableTests.recalculate();
				availableTests.layout(true);
				recalculate();
				layout(true);
			}
		});
	}

	private WitsTable toTable(ExamListDTO availableExams) {
		// todo: i18n
		WitsTable availableExamTable =
			new WitsTable(new String[]{"Test Name", "Subject", "# of Questions", "Time Limit", "Available From",
			                           "Available Until", "Needed", "Team", "Comments"});
		ExamSummaryDTO[] summaries = availableExams.getSummaries();
		for (int i = 0; i < summaries.length; i++) {
			ExamSummaryDTO summary = summaries[i];
			TableItem item = new TableItem(new Object[]{summary.getTestName(),
			                                            summary.getSubjectName(),
			                                            new Integer(summary.getTotalQuestions()),
			                                            new Integer(summary.getMaxMinutes()),
			                                            summary.getAvailableSince(),
			                                            summary.getAvailableUntil(),
			                                            summary.getRequiredTools(),
			                                            new Boolean(summary.isTeamwork()),
			                                            summary.getComments()});
			item.setData("id", summary.getTestId());
			availableExamTable.add(item);
		}

		// todo: 30 is only an estimate, need a better way to ensure correct sizing!
		availableExamTable.setHeight(summaries.length * 30);

		availableExamTable.disableTextSelection(true);
		availableExamTable.enableEvents(true);
		availableExamTable.sort(0, Style.ASC);
		// all columns are sortable and resizable
		for (int i = 0; i < availableExamTable.getColumnCount(); i++) {
			TableColumn column = availableExamTable.getColumnModel().getColumn(i);
			column.setSortable(true);
			column.setResizable(true);
		}

		TableColumn column = availableExamTable.getColumnModel().getColumn(2);
		column.setRenderer(new NumberCellRenderer("##"));
		column.setAlignment(Style.RIGHT);

		column = availableExamTable.getColumnModel().getColumn(3);
		column.setRenderer(new NumberCellRenderer("##"));
		column.setAlignment(Style.RIGHT);

		column = availableExamTable.getColumnModel().getColumn(4);
		column.setRenderer(new DateTimeCellRenderer(FormatUtil.LONG_DATE));
		column.setAlignment(Style.RIGHT);

		column = availableExamTable.getColumnModel().getColumn(5);
		column.setRenderer(new DateTimeCellRenderer(FormatUtil.LONG_DATE));
		column.setAlignment(Style.RIGHT);

		availableExamTable.addListener(Events.CellDoubleClick | Events.KeyPress, new Listener() {

			public void handleEvent(BaseEvent be) {
				AppContext.showLoading();
				Viewport viewport = AppContext.getViewport();
				viewport.remove(AppContext.getMainPanel());
				viewport.add(new ExamPanel(), new BorderLayoutData(Style.CENTER));
				viewport.layout(true);
				AppContext.hideLoading();
			}
		});

		return availableExamTable;
	}

	private void initTestResults() {
		ContentPanel testResults = new ContentPanel(Style.HEADER | Style.COLLAPSE);
		testResults.setText("Test Results");
		testResults.setWidth("100%");
		testResults.setFrame(false);
		testResults.setStyleName("pn-test-results");

		add(testResults);
	}
}
